import logging
import time
from urllib.parse import urljoin
from common.send_requests import sendRequest
from Model.environment import Environment
from Model.user import PcUser, AppUser
from Model.sql import Sql


class SalesOrder:
    # 司机姓名
    driver_name = None
    # 司机身份证号
    driver_id_card = None
    # 司机手机号
    driver_phone = None
    # 司机ID
    driver_driver_id = None
    # 配送规则下的承运商名称
    distribution_rules_carrier_name = None
    # 配送规则下的承运商编号
    distribution_rules_carrier_code = None
    # 配送路由id
    distribution_rule_id = None
    # 配送路由名称
    distribution_rule_name = None
    # 配送路由车牌号
    distribution_rules_car_number = None
    # 装车单号
    transport_no = None
    # 运输方式 -1=未知,0=自提,1=汽运,2=海运,3=河运
    transport_mode = None
    # 订单收货地址
    receive_address = {
        # "city": "连云港市",
        # "country": "中国",
        # "full": "江苏省连云港市",
        # "state": "江苏省",
        # "street": "",
        # "zipCode": "320700"
    }
    # 订单物料
    goods = []
    # 请求头
    headers = {
        'Content-Type': 'application/json',
    }

    def __init__(self, env, puser, auser, sales_order_no, sql, logger: logging.Logger):
        self.code = 0
        self.env: Environment = env
        self.sql: Sql = sql
        self.puser: PcUser = puser
        self.auser: AppUser = auser
        self.sales_order_no = sales_order_no
        self.untread_order_list = []
        self.logger = logger
        self.status = None
        self.info = None

    def sales_order_query(self):
        # 销售订单查询
        url = urljoin(self.env.realmName, "sales-order/search")
        params = {
            "orderNo": self.sales_order_no,
            "includeDetails": True,
            "IncludeOrderStocks": True,
            "SkipCount": 0,
            "MaxResultCount": 50
        }
        res = sendRequest(url, "GET", params=params,
                          headers=self.puser.headers, msg="销售单查询")
        if res.status_code == 200:
            if len(res.json()["items"]):
                self.code = 1
                self.info = res.json()["items"][0]
                print(f"订单查询成功: {res.text}")
                self.logger.info(f"订单查询成功: {res.text}")
                self.status = "订单查询成功"
                self.receive_address = self.info["receiveRegion"]
                self.logger.info(f"订单收货地址: {self.receive_address}")
                self.goods = self.info["details"]
                for gs in self.goods:
                    self.logger.info(f"订单物料: {gs}")
                self.transport_mode = self.info["transportMode"]
            else:
                self.code = 0
                print(f"未找到订单: {res.text}")
                self.logger.info(f"未找到订单: {res.text}")
                self.status = f"未找到订单: {res.text}"
        else:
            self.code = 0
            print(f"查询报错: {res.text}")
            self.logger.info(f"查询报错: {res.text}")
            self.status = "查询订单报错"

    def untread_order_query(self):
        # 查询退回单
        url = urljoin(self.env.realmName, "return-request-order/search")
        params = {
            "SourceNo": self.sales_order_no,
            "MaxResultCount": 50,
            "status": 1,
            "SkipCount": 0,
            "BeginRequestTime": "",
            "EndRequestTime": "",
            "BeginAuditTime": "",
            "EndAuditTime": "",
        }
        res = sendRequest(url, "GET", params=params,
                          headers=self.puser.headers, msg="退回单查询")
        if res.status_code == 200:
            self.untread_order_list = [items["requestNo"]
                                       for items in res.json()["items"]]
            self.status = "查询成功"
            self.code = 1
            self.logger.info(f"退回单查询成功: {res.text}")
        else:
            self.status = f"退回单查询报错: {res.text}"
            self.logger.info(f"退回单查询报错: {res.text}")
            self.code = 0

    def untread_order_audit(self):
        # 退回操作审核
        self.untread_order_query()
        if not self.untread_order_list:
            self.status = "未找到退回单"
            self.logger.info(f"未找到退回单")
            return
        for return_order_no in self.untread_order_list:
            url = urljoin(self.env.realmName, "oa-system/return-audit")
            data = {
                "body": {
                    "auditStatus": 1,
                    "returnOrderNo": f"{return_order_no}",
                    "auditTime": time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                    "auditRemark": f"{return_order_no}退货通过"
                }
            }
            res = sendRequest(url, "post", data, self.puser.headers, "退货审核成功")
            if res.status_code == 200:
                if res.json()["MESASSEG"] == "同步成功":
                    self.status = "退货审核成功"
                    self.code = 1
                    self.logger.info(f"退货审核成功: {res.text}")
                else:
                    self.status = res.text
                    self.code = 0
                    self.logger.info(f"退货审核失败: {res.text}")
            else:
                self.status = f"请求报错: {res.text}"
                self.code = 0
                self.logger.info(f"请求报错: {res.text}")

    def get_untread_transport_order(self):
        # 获取待退货的装车单
        url = urljoin(self.env.realmName,
                      "transport-order/search-finish-product")
        params = {
            "skipCount": 0,
            "maxResultCount": 50,
            "GetMergeType": True,
            "IncludeDetails": True,
            "returnType": 1,
            "SourceNo": self.sales_order_no
        }
        res = sendRequest(url, "GET", params=params,
                          headers=self.puser.headers)
        if res.status_code == 200:
            transport_order_list = [transport_order["transportOrderNo"]
                                    for transport_order in res.json()["items"]]
            self.logger.info(f"待退货的装车单:")
            for no in transport_order_list:
                self.logger.info(f"{no}")
            self.logger.info("=======================================")
            if len(transport_order_list) == 0:
                self.status = "未找到待退货的装车单"
                self.code = 0
                self.logger.info(f"未找到待退货的装车单")
            else:
                self.untread_transport_order_no = transport_order_list[0]
                transport_list_str = ",".join(transport_order_list)
                self.status = f"{transport_list_str} 返回第一个装车单: {self.untread_transport_order_no}"
                self.code = 1
                self.logger.info(f"查询成功: {res.text}")

    def presell_plan_distribution(self):
        # 预售计划分配
        url = urljoin(self.env.realmName, "pre-sale/trigger-allocate-loading")
        data = {
            "trigger": "G测试发放"
        }
        res = sendRequest(url, "post", js=data,
                          headers=self.puser.headers, msg="预售库存匹配计划单")
        if res.status_code == 204:
            self.status = "预售计划分配成功"
            print(f"预售计划分配成功: {res.text}")
        else:
            self.status = "预售计划分配失败"
            print(f"预售计划分配异常: {res.text}")

    def presell_plan_retrieve(self):
        # 预售计划回收
        url = urljoin(self.env.realmName, "pre-sale/trigger-stock-recovery")
        data = {
            "no": self.sales_order_no
        }
        res = sendRequest(url, "post", js=data,
                          headers=self.puser.headers, msg="预售库存回收计划单")
        if res.status_code == 204:
            self.status = "预售计划回收成功"
            print(f"预售计划回收成功: {res.text}")
        else:
            self.status = "预售计划回收异常"
            print(f"预售计划回收异常: {res.text}")

    def presell_plan_force_distribution(self):
        # 设置预售计划回收时间马上过期
        self.sql.set_retrieve_expire(self.sales_order_no)
        self.status = self.sql.status

    def presell_plan_force_retrieve(self):
        # 预售计划超时回收释放
        self.sql.set_retrieve_release(self.sales_order_no)
        self.status = self.sql.status

    def get_distribution_rules(self):
        # 获取配送规则
        url = urljoin(self.env.realmName, "driver-client/delivery-rule")
        res = sendRequest(url, "get", headers=self.auser.headers, msg="获取配送规则")
        if res.status_code == 200:
            self.is_tag = True
            res_js = res.json()
            self.distribution_rule_id = res_js["id"]
            self.distribution_rule_name = res_js["name"]
            for carrier in res_js["carriers"]:
                if carrier["name"] == "GG bond！！":
                    self.distribution_rules_carrier_code = carrier["code"]
                    self.distribution_rules_carrier_name = carrier["name"]

            self.status = "获取配送规则成功"
        else:
            self.is_tag = False
            self.status = f"获取配送规则报错: {res.text}"

    def get_distribution_rules_car(self):
        # 获取配送规则车牌号
        url = urljoin(self.env.realmName, "driver-client/carrier-vehicles")
        params = {
            "carrierCode": self.distribution_rules_carrier_code
        }
        res = sendRequest(url, "get", headers=self.auser.headers,
                          params=params, msg="获取配送规则车牌号")
        if res.status_code == 200:
            self.is_tag = True
            res_js = res.json()
            self.distribution_rules_car_number = res_js[0]["name"]
        else:
            self.is_tag = False
            self.status = f"获取配送规则车牌号报错: {res.text}"

    def distribution_sheet_bespeak(self):
        # 配送单预约
        url = urljoin(self.env.realmName, "driver-client/reserve-delivery")
        data = {
            # 短途路由Id
            "deliveryRuleId": self.distribution_rule_id,
            # 承运商编号
            "carrierCode": self.distribution_rules_carrier_code,
            # 车牌号码
            "plateNumber": self.distribution_rules_car_number
        }
        res = sendRequest(url, "post", js=data,
                          headers=self.auser.headers, msg="配送单预约")
        if res.status_code == 200:
            r = res.json()
            self.isReserve = r["isReserve"]
            if self.isReserve:
                self.is_tag = True
                self.status = "配送单预约成功"
            else:
                self.is_tag = False
                self.status = f"配送单预约失败 isReserve: {self.isReserve}"
        else:
            self.is_tag = False
            self.status = f"配送单预约报错: {res.text}"

    def distribution_sheet_bespeak_query(self):
        # 司机短途配送预约查询
        url = urljoin(self.env.realmName,
                      "transport-order/search-by-delivery-reserve")
        params = {
            "CarrierCode": self.distribution_rules_carrier_code,
            "Phone": self.auser.driver_phone,
            "PlateNumber": self.distribution_rules_car_number,
            "MaxResultCount": "50",
            "SkipCount": "0",
            "type": "1",
            "BeginReserveTime": "",
            "EndReserveTime": "",
            "BeginSigninTime": "",
            "EndSigninTime": ""
        }
        res = sendRequest(url, "get", params=params, headers=self.puser.headers,
                          msg="司机短途配送预约查询")
        if res.status_code == 200:
            r = res.json()
            if len(r["items"]) > 0:
                self.is_tag = True
                self.transport_no = r["items"][0]["transportOrderNo"]
                self.distribution_rules_car_number = r["items"][0]["plateNumber"]
                self.driver_name = r["items"][0]["name"]
                self.driver_phone = r["items"][0]["phone"]
                self.driver_id_card = r["items"][0]["idCard"]
                self.driver_driver_id = r["items"][0]["driverId"]
                self.status = f"司机短途配送预约查询成功，装车单号：{self.transport_no}"
            else:
                self.is_tag = False
                self.status = "司机短途配送预约查询失败，没有预约单"
        else:
            self.is_tag = False
            self.status = f"司机短途配送预约查询失败，{res.text}"

    def distribution_sheet_bespeak_audit(self):
        # 配送单预约审核
        url = urljoin(self.env.realmName, "transport-order/audit")
        data = {
            # 运输单号
            "orderNo": self.transport_no,
            # 审核通过或拒绝 0=审核拒绝,1=审核通过
            "audit": 1,
            # 说明、原因、备注
            "content": "说明、原因、备注",
            # 入厂车牌号
            "enterPlateNumber": self.distribution_rules_car_number,
            "enterDriverId": self.driver_driver_id
        }
        res = sendRequest(url, "post", data, self.puser.headers, "配送单预约审核")
        if res.status_code == 204:
            self.status = "配送单预约审核成功"
        else:
            self.status = f"配送单预约审核失败，{res.text}"

    def distribution_sheet_signin(self):
        # 司机签到
        url = urljoin(self.env.realmName,
                      f"driver-client/transport-order-signin")
        data = {
            "transportOrderNo": self.transport_no,
            "position": {
                "y": 119.173798,
                "x": 34.848408
            },
            "address": "江苏省连云港市赣榆区青口镇鸥翔路龙湖海岸华庭"
        }
        res = sendRequest(url, "post", js=data,
                          headers=self.auser.headers, msg="司机签到")
        if res.status_code == 200:
            if res.json()["status"] == "Succ":
                self.status = "司机签到成功"
            else:
                self.status = res.json()["exceptionMsg"]
        else:
            self.status = f"司机签到失败: {res.text}"

    def distribution_sheet_distribution(self):
        # 配送单分配
        url = urljoin(self.env.realmName, "plan-order-task/allot-by-source-no")
        data = {
            "sourceNo": self.sales_order_no,
            "sourceType": 1
        }
        res = sendRequest(url, "post", data,
                          headers=self.puser.headers, msg="分配计划单")
        if res.status_code == 200:
            self.status = "配送单分配接口调用成功"
        else:
            self.status = f"配送单分配接口调用失败: {res.text}"

    def get_transport_order_sales(self):
        # 查询装车单的销售单
        url = urljoin(self.env.realmName, "transport-order/detail")
        params = {
            "orderNo": self.transport_no,
            "IncludeLoading": True
        }
        res = sendRequest(url, "get", headers=self.puser.headers,
                          params=params, msg="运输单详情")
        self.info = res.json()
        sourceNo = self.info["sourceNo"]
        if self.sourceNo == sourceNo:
            self.status = "销售单分配成功"
        else:
            self.status = f"销售单分配失败，分配的销售单号：{sourceNo}"

    def sales_reset(self):
        # 销售单重新判断
        url = urljoin(self.env.realmName, "plan-order/running")
        data = {
            "sourceNo": self.sales_order_no,
            "sourceType": 1
        }
        res = sendRequest(url, "post", data, self.puser.headers, "订单重新判断")
        if res.status_code == 204:
            self.status = "重置销售单成功"
            self.code = 1
        else:
            print(f"重置销售单失败: {res.text}")
            self.status = "重置销售单失败"
            self.code = 0
